#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "hi_gpio.h"
#include "hi_io.h"
#include "hi_pwm.h"
#include "hi_time.h"

// --- 硬件引脚定义 ---
#define F1_KEY      11  // 按键1（控制《好运来》）
#define F2_KEY      12  // 按键2（控制《字母歌》）
#define BEEP_PIN    9   // 蜂鸣器GPIO 9 (PWM0)

// --- 全局变量：当前要播放的歌曲 ID ---
// 0: 停止, 1: 好运来, 2: 字母歌
static volatile int g_current_song_id = 0;

// --- 音符频率分频表 (40MHz时钟) ---
static const uint16_t g_tuneFreqs[] = {
    0,      // 0: 休止符
    // 中音 1-7 (Do - Si) -> 索引1-7
    76445, 68104, 60674, 57268, 51021, 45455, 40495,
    // 高音 1-7 (Do - Si) -> 索引8-14
    38223, 34052, 30338, 28635, 25511, 22728, 20249,
    // 低音 1-7 (Do - Si) -> 索引15-21（补充低音，适配歌曲音域）
    152890, 136208, 121348, 114536, 102042, 90910, 80990
};

// --- 歌曲1: 好运来 (简谱核心片段) ---
// 简谱参考：1 2 3 5 | 5 3 2 1 | 2 3 5 6 | 6 5 3 2 | 1 - - - | 3 3 5 6 | 5 3 2 1 | 1 - - -
static const uint8_t g_score_luck[] = {
    1,2,3,5, 5,3,2,1, 2,3,5,6, 6,5,3,2, 1,0,0,0, 3,3,5,6, 5,3,2,1, 1,0,0,0
};
// 对应节拍 (4=一拍，0=休止符)
static const uint8_t g_time_luck[] = {
    4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 8,4,4,4, 4,4,4,4, 4,4,4,4, 8,4,4,4
};

// --- 歌曲2: 字母歌 (ABC Song，简谱) ---
// 简谱参考：1 2 3 1 | 1 2 3 1 | 3 4 5 - | 3 4 5 - | 5 6 5 4 3 1 | 5 6 5 4 3 1 | 1 8 1 - | 1 8 1 -
static const uint8_t g_score_abc[] = {
    1,2,3,1, 1,2,3,1, 3,4,5,0, 3,4,5,0, 5,6,5,4,3,1, 5,6,5,4,3,1, 1,8,1,0, 1,8,1,0
};
// 对应节拍
static const uint8_t g_time_abc[] = {
    4,4,4,4, 4,4,4,4, 4,4,8,4, 4,4,8,4, 3,1,3,1,4,4, 3,1,3,1,4,4, 4,4,8,4, 4,4,8,4
};

// --- 初始化函数 ---
static void DeviceInit(void)
{
    // 1. 初始化 GPIO 模块
    hi_gpio_init();

    // 2. 初始化蜂鸣器 (GPIO 9 -> PWM0)
    hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_PWM0_OUT);
    hi_pwm_init(HI_PWM_PORT_PWM0);
    hi_pwm_set_clock(PWM_CLK_XTAL);

    // 3. 初始化按键 F1 (GPIO 11)
    hi_io_set_func(F1_KEY, HI_IO_FUNC_GPIO_11_GPIO);
    hi_io_set_pull(F1_KEY, HI_IO_PULL_UP);
    hi_gpio_set_dir(F1_KEY, HI_GPIO_DIR_IN);

    // 4. 初始化按键 F2 (GPIO 12)
    hi_io_set_func(F2_KEY, HI_IO_FUNC_GPIO_12_GPIO);
    hi_io_set_pull(F2_KEY, HI_IO_PULL_UP);
    hi_gpio_set_dir(F2_KEY, HI_GPIO_DIR_IN);
}

// --- 按键中断处理 ---
static void F1_Pressed(char *arg)
{
    (void)arg;
    g_current_song_id = 1; // 切换到《好运来》
    printf("Switch to Song 1: Good Luck Comes\n");
}

static void F2_Pressed(char *arg)
{
    (void)arg;
    g_current_song_id = 2; // 切换到《字母歌》
    printf("Switch to Song 2: ABC Song\n");
}

// --- 播放逻辑 (支持打断) ---
// 返回值: 0=正常播完, 1=被切歌打断
static int PlayMelody(const uint8_t *notes, const uint8_t *durations, size_t len, int song_id_check)
{
    for (size_t i = 0; i < len; i++) {
        // 每次播放前检查是否被切歌
        if (g_current_song_id != song_id_check) {
            hi_pwm_stop(HI_PWM_PORT_PWM0); 
            return 1; 
        }

        uint8_t note = notes[i];
        // 音符索引越界时设为休止符
        if (note >= sizeof(g_tuneFreqs)/sizeof(g_tuneFreqs[0])) note = 0;

        uint16_t freqDiv = g_tuneFreqs[note];
        // 计算节拍时长 (基础单位125ms，适配原节拍逻辑)
        uint32_t duration_us = durations[i] * (125 * 1000); 

        if (note > 0) { // 非休止符，播放音符
            hi_pwm_start(HI_PWM_PORT_PWM0, freqDiv / 2, freqDiv);
            hi_udelay(duration_us); 
            hi_pwm_stop(HI_PWM_PORT_PWM0);
        } else { // 休止符，仅延时
            hi_udelay(duration_us);
        }
        
        hi_udelay(20000); // 音符间短暂间隔，避免连音
    }
    return 0; 
}

// --- 主任务 ---
static void MusicTask(void *arg)
{
    (void)arg;
    DeviceInit();

    // 注册按键中断（下降沿触发，适配上拉电阻配置）
    hi_gpio_register_isr_function(F1_KEY, HI_INT_TYPE_EDGE, HI_GPIO_EDGE_FALL_LEVEL_LOW, &F1_Pressed, NULL);
    hi_gpio_register_isr_function(F2_KEY, HI_INT_TYPE_EDGE, HI_GPIO_EDGE_FALL_LEVEL_LOW, &F2_Pressed, NULL);

    printf("Music Task Started. Press F1 (Good Luck Comes) or F2 (ABC Song).\n");

    while (1) {
        if (g_current_song_id == 1) {
            // 播放《好运来》，播完后重置为停止状态
            int ret = PlayMelody(g_score_luck, g_time_luck, sizeof(g_score_luck), 1);
            if (ret == 0) g_current_song_id = 0; 
        } 
        else if (g_current_song_id == 2) {
            // 播放《字母歌》，播完后重置为停止状态
            int ret = PlayMelody(g_score_abc, g_time_abc, sizeof(g_score_abc), 2);
            if (ret == 0) g_current_song_id = 0; 
        } 
        else {
            usleep(100000); // 无歌曲播放时，低功耗延时
        }
    }
}

// --- 任务创建入口 ---
static void MusicEntry(void) {
    osThreadAttr_t attr = {
        .name = "MusicTask",
        .stack_size = 4096,
        .priority = osPriorityNormal,
    };
    osThreadNew(MusicTask, NULL, &attr);
}

// --- 鸿蒙系统启动入口 ---
SYS_RUN(MusicEntry);